package object3;

/**
 * 匿名内部类细节
 */
public class AnonymousInnerClassDetail {

    public static void main(String[] args) {
        /*
            匿名内部类的语法比较奇特，因为它既是一个类的定义，同时本身也是一个对象
            所以既有类的特征也有对象的特征
            可以直接访问外部类所有成员，包括私有的
            不能添加访问修饰符，因为它的地位就是一个局部变量
            作用域：仅仅在定义它的方法或代码块中
            匿名内部类 ——访问——》外部类成员 直接访问
            外部其他类 ——不能访问——》匿名内部类
            如果外部类和匿名内部类的成员重名时，匿名内部类访问时遵循就近原则，如果想访问外部类的成员
            可以使用 外部类名.this.成员
         */

        Outer05 outer05 = new Outer05();

        outer05.f1();

        //外部其他类---不能访问----->匿名内部类
        System.out.println("main outer05 hashcode=" + outer05);
    }
}

class Outer05 {

    private int n1 = 99;

    public void f1() {
        Per per = new Per() {

            private int n1 = 88;

            @Override
            public void hi() {
                System.out.println("匿名内部类重写了hi方法 n1=" + n1 + ",外部类的n1=" + Outer05.this.n1);
                System.out.println("Outer05.this hashcode = " + Outer05.this.hashCode());
            }
        };
        per.hi();//动态绑定 运行类型 Outer05$1

        //也可以直接调用，匿名内部类本身也是返回对象
        //class 匿名内部类 extends Per{}
        new Per() {

            @Override
            public void hi() {
                System.out.println("匿名内部类重写了 hi 方法，哈哈...");
            }

            @Override
            public void ok(String str) {
                super.ok(str);
            }
        }.ok("jack");
    }


}

class Per { //类

    public void hi() {
        System.out.println("Per hi()");
    }

    public void ok(String str) {
        System.out.println("Per ok()" + str);
    }
}

//抽象类/接口...